package net.web.struts.action;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.constant.IConstant;
import net.entity.AttemptedQuestion;
import net.entity.QuestionInfo;
import net.entity.User;
import net.handler.IProcessHandler;
import net.handler.ProcessHandler;
import net.lwf.web.constant.IWebConstant;
import net.web.struts.action.form.BaseActionForm;
import net.web.util.WebUtil;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;


public abstract class BaseAction extends DispatchAction {

	private String operation;
	
	public abstract IProcessHandler getHandler(HttpServletRequest request);
	
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		if(!isValidUser(request)) {
			return mapping.findForward("login");
		}
		else {
			this.setOperation(request);
		}
		return super.execute(mapping, form, request, response);
	}
	
	public ActionForward checkanswer(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		String useranswer = getUserAnswer(request);
		AttemptedQuestion lastattemptedQ = (AttemptedQuestion) WebUtil.getAttribute(request, IConstant.LAST_QUESTION);
		PrintWriter out = response.getWriter();

		String answermsg = "<font color=\"red\"> Your answer is wrong.... Please try again.</font>";
		if(!lastattemptedQ.isAnsweredCorrectly()) {
			if (lastattemptedQ.getAttempts() > IConstant.MAX_ATTEMPTS) {
				answermsg = "<font color=\"red\"> You have reached maximum number of attempts to answer this question. <br>" +
					        "The correct answer is: " + lastattemptedQ.getAnswer() + "<br>" +
						    "You may click next for the next question.</font>";
			} else {
				lastattemptedQ.attempted();
				if (getHandler(request).matchAnswer(useranswer, lastattemptedQ)) {
					lastattemptedQ.setAnsweredCorrectly(true);
					answermsg = "<font color=\"blue\"> The answer is correct. You may click next for the next question. </font>";
					
				}
			}			
		}
		else {
			answermsg = "<font color=\"blue\"> You have already entered the correct answer. Please click next for the next question. </font>";
		}
		response.setContentType("text/html");
		out.println(answermsg);
		out.flush();

		return null; // Not forwarding to anywhere, response is fully-cooked

	}
	
	@SuppressWarnings("unchecked")
	public void setQuestionData(HttpServletRequest request, AttemptedQuestion question) {
		WebUtil.setAttribute(request, IConstant.LAST_QUESTION, question);
		Object object = WebUtil.getAttribute(request, IConstant.QUESTION_INFO);
		Map<String, List<AttemptedQuestion>> mapQData;
		List<AttemptedQuestion> attemptedQs = null;
		if(object == null) {
			mapQData = new HashMap<String, List<AttemptedQuestion>>();
		}
		else {
			mapQData = (Map<String, List<AttemptedQuestion>>) object;
		}
		
		String key = question.getKey();
		if(mapQData.containsKey(key)) {
			attemptedQs = mapQData.get(key);
		}
		else {
			attemptedQs = new ArrayList<AttemptedQuestion>();
		}
		attemptedQs.add(question);
		mapQData.put(key, attemptedQs);
		//Set question number
		WebUtil.setAttribute(request, IConstant.QUESTION_INFO, mapQData);
	}

	private boolean isValidUser(HttpServletRequest request) {
		User user = (User) WebUtil.getAttribute(request, IConstant.USER);	
		if(user != null && user.getUserId() != null) {
			return true;
		}
		return false;
	}
	
	private void setOperation(HttpServletRequest request) {
		String operation_in_req = request.getParameter(IConstant.OPERATION);
		if(operation_in_req != null) {
			this.operation = operation_in_req;
			WebUtil.setAttribute(request, IConstant.OPERATION, operation_in_req);
		}
		else {
			this.operation = (String) WebUtil.getAttribute(request, IConstant.OPERATION);
		}
	}
	
	@SuppressWarnings("unchecked")
	public int getQuestionNumber(HttpServletRequest request, String key) {
		Map<String, List<AttemptedQuestion>> mapQData 
		  = (Map<String, List<AttemptedQuestion>>) WebUtil.getAttribute(request, IConstant.QUESTION_INFO);
		if(mapQData != null) {
			List<AttemptedQuestion> attemptedQs = mapQData.get(key);
			if(attemptedQs != null) {
				return attemptedQs.size();
			}
		}
		return 1;
	}
	
	public String getOperation() {
		return this.operation;
	}
	
	public String getUserAnswer(HttpServletRequest request) {
		return request.getParameter("useranswer");
	}
	
	public void setQuestionData(HttpServletRequest request, ProcessHandler handler, BaseActionForm form) {
		QuestionInfo qinfo = handler.generateSingle();
		//Set the question data
		setQuestionData(request, qinfo);
		//Set Radio Answers
		WebUtil.setAttribute(request, IWebConstant.RADIO_ANSWERS, qinfo.getRadioAnswerChoices());
		
		//Set form data
		form.setHtmlQuestion(qinfo.getHtmlQuestion());
		form.setQuestionNumber(getQuestionNumber(request, getOperation()));
	}
	
} //BaseAction


